package com.bachelor.community.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.log.Log;
import com.bachelor.community.mapper.UserMapper;
import com.bachelor.community.model.dto.UserDTO;
import com.bachelor.community.model.entity.User;
import com.bachelor.community.model.vo.UserVO;
import com.bachelor.community.service.intf.UserService;
import com.bachelor.community.utils.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;
    private static final Log LOG = Log.get();

    private User getUser(UserDTO userDTO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", userDTO.getAccount());
        queryWrapper.eq("password", SecureUtil.md5(userDTO.getPassword()));
        User one;
        try {
            one = getOne(queryWrapper);
        } catch (Exception e) {
            LOG.error(e);
            throw new ServiceException("500", "服务器故障");
        }
        return one;
    }

    @Override
    public UserVO login(UserDTO userDTO) {
        User one = getUser(userDTO);
        if (!ObjectUtil.isEmpty(one)) {
            one.setLastLogin(DateUtil.date().toTimestamp());
            updateById(one);
            UserVO userVO = new UserVO();
            BeanUtil.copyProperties(one, userVO, true);
            // 密钥
            byte[] key = one.getPassword().getBytes();
            String token = JWT.create()
                    .setPayload("user_id", one.getId())
                    .setPayload("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24) //过期时间：1天
                    .setKey(key)
                    .sign();
            userVO.setToken(token);
            return userVO;
        } else {
            throw new ServiceException("401", "用户名或密码错误");
        }
    }

    @Override
    public User register(UserDTO userDTO) {
        User one = getUser(userDTO);
        if (ObjectUtil.isEmpty(one)) {
            one = User.builder().account(userDTO.getAccount())
                    .password(SecureUtil.md5(userDTO.getPassword()))
                    .username(userDTO.getUsername())
                    .email(userDTO.getEmail())
                    .createTime(DateUtil.date().toTimestamp()).build();
            save(one);
        } else {
            throw new ServiceException("422", "用户已存在");
        }
        return one;
    }

    @Override
    public UserVO getUserVOById(Integer userId) {
        User user = getById(userId);
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public UserVO partialUpdateUser(Integer userId, UserDTO userDTO) {
        User user = getById(userId);
        if (StrUtil.isBlank(userDTO.getPassword())) {
            user.setUsername(userDTO.getUsername());
            user.setEmail(userDTO.getEmail());
            user.setIntroduction(userDTO.getIntroduction());
            user.setCredit(userDTO.getCredit());
            user.setRole(userDTO.getRole());
        } else {
            user.setPassword(SecureUtil.md5(userDTO.getPassword()));
        }
        updateById(user);
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO, true);
        return userVO;
    }

    @Override
    public IPage<UserVO> listUsersOrderByLikeCount(Integer currentPage, Integer pageSize) {
        IPage<UserVO> page = new Page<>(currentPage, pageSize);
        userMapper.listUsersOrderByLikeCount(page);
        return page;
    }

    @Override
    public List<String> listClassNumbers() {
        return userMapper.listClassNumbers();
    }
}
